package com.teichmann.core.targets.online;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.client.HttpClient;
import org.apache.log4j.Logger;
import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Parser;
import org.htmlparser.Tag;
import org.htmlparser.lexer.Lexer;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.NodeVisitor;

import com.teichmann.bo.Car;
import com.teichmann.bo.Seller;
import com.teichmann.core.OnlinePage;
import com.teichmann.core.annotations.Url;
import com.teichmann.core.util.ConnectionUtils;
import com.teichmann.core.util.CrawlerUtils;

@Url(value = "http://www.carrosnaserra.com.br/index.php?conteudo=pesquisa&pagina=1&categoria=%&cidade=%&ano1=...&ano2=...")
public class CarroNaSerra implements OnlinePage {

	Logger logger = Logger.getLogger(this.getClass().getSimpleName());
	HttpClient client = ConnectionUtils.getClient();
	
	
	ArrayList<Car> cars = new ArrayList<Car>();
	NodeVisitor visitor = new NodeVisitor() {

		@Override
		public void visitTag(Tag tag) {
			String name = tag.getTagName();
			if ("tr".equalsIgnoreCase(name)
					&& (tag.getAttribute("bgcolor") != null && (
							tag.getAttribute("bgcolor").contains("#cdf1d8".toUpperCase()) || 
							tag.getAttribute("bgcolor").contains("#edfaf1".toUpperCase())))) {

				Car c = extractInformation(tag);
				if (c != null){
					cars.add(c);
				}

			}
		}
	};

	public ArrayList<Car> performSearch(String parameter) throws IOException {
		
		logger.debug("Entering "+this.getClass().getSimpleName());

		String modelo = "&modelo=" + parameter;

		String responseBody = ConnectionUtils.get(client,this.getClass()
				.getAnnotation(Url.class).value()
				+ modelo);

		int numberOfPages = Integer
				.parseInt(org.apache.commons.lang.StringUtils.substringBetween(
						responseBody, "Sua pesquisa encontrou <b>",
						"</b> registros"));
		numberOfPages = (numberOfPages % 50 == 0) ? numberOfPages/50 : (numberOfPages/50) +1;

		for (int x = 1; x <= numberOfPages; x++) {
						
			responseBody = ConnectionUtils
					.get(client, CARROSNASERRA_URL+"/index.php?conteudo=pesquisa&pagina="
							+ x
							+ "&categoria=%&cidade=%&ano1=...&ano2=..."
							+ modelo);

			Parser parser = new Parser(new Lexer(responseBody));
			try {
				parser.visitAllNodesWith(visitor);
			} catch (ParserException e) {
				e.printStackTrace();
			}
			
			
			
		}

		return cars;

	}

	public Car extractInformation(Tag line) {
		Car car = new Car();
		int count = 1;
		try {

			NodeList details = line.getChildren();
			details = details.extractAllNodesThatMatch(new NodeFilter() {
				public boolean accept(Node arg0) {
					if (arg0 instanceof TableColumn) {
						return true;

					}

					return false;
				}

			});

			Pattern intOnly = Pattern.compile("\\d*");

			car.setModelo(CrawlerUtils.removeUnusedFields(details.elementAt(1).getChildren().elementAt(0).getChildren().elementAt(0).getText()));

			// ano fabricacao
			String anoModelo = CrawlerUtils.removeUnusedFields(details.elementAt(2).getChildren().elementAt(0).getChildren().elementAt(0).getText());
			Matcher matcher = intOnly.matcher(anoModelo.trim());
			if (matcher.find()) {
				car.setAnoModelo(new Integer(matcher.group()));
			} else {
				car.setAnoModelo(new Integer(anoModelo));
			}
			car.setAnoFabricacao(car.getAnoModelo());
			
			car.setCor(CrawlerUtils.removeUnusedFields(details.elementAt(3).getChildren().elementAt(0).getChildren().elementAt(0).getText()));
			car.setCombustivel("GASOLINA");
			car.setValor(CrawlerUtils.removeUnusedFields(details.elementAt(4).getChildren().elementAt(0).getChildren().elementAt(0).getText()));
			car.setUrl(CARROSNASERRA_URL
					+ ((LinkTag) details.elementAt(5).getChildren()
							.elementAt(0).getChildren().elementAt(0)).getLink());
			car.setRevenda(new Seller(this.getClass().getSimpleName()));

			// addExtra(car);
			
		} catch (Exception e) {
			logger.error("Error", e);
			e.printStackTrace();
			return null;
		}

		return car;

	}
	
	
	private void addExtra(final Car car) throws IOException {
		
		String temp = car.getUrl().substring(car.getUrl().indexOf("&")+1);
		temp  = CARROSNASERRA_URL+"anuncio_detalhes.php?"+temp;
		String responseBody = ConnectionUtils.get(client, temp);
		
		Parser parser = new Parser(new Lexer(responseBody));
		try{
	
			
		parser.visitAllNodesWith(new NodeVisitor() {

			@Override
			public void visitTag(Tag tag) {
				
				
				if(car.getFotos()!= null && car.getFotos().size()== 4){
					return;
				}
				
				String name = tag.getTagName();
				if ("IMG".equalsIgnoreCase(name)
						&& (tag.getAttribute("name") == null)
						&& (tag.getAttribute("class") != null &&
							tag.getAttribute("class").equals("links_imagens"))) {

					car.setFotos(car.getFotos() == null ? new ArrayList<String>(): car.getFotos());
					car.getFotos().add(CARROSNASERRA_URL + tag.getAttribute("src"));
				}
			}
			});
		}
		catch (ParserException e) {
			e.printStackTrace();
		}
		
	}
	

	
	public ArrayList<Car> performSearch(String parameter, HttpClient client)throws IOException {
		this.client = client;
		return performSearch(parameter);
	}
}
